package org.ns.learn.rpc.client.rpcinterface;

import org.ns.learn.rpc.client.RpcClient;
import org.ns.learn.rpc.client.RpcClientResponse;
import org.ns.learn.rpc.codec.ParameterType;
import org.ns.learn.rpc.codec.RpcRequest;
import org.ns.learn.rpc.codec.RpcResponse;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Collection;

public class RpcProxy implements InvocationHandler {

    RpcClients clients;
    String beanName;

    public RpcProxy(RpcClients clients, String beanName) {
        this.clients = clients;
        this.beanName = beanName;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] values) throws Throwable {
        String methodName = method.getName();
        Class<?>[] types = method.getParameterTypes();
        ParameterType[] parameterTypes = new ParameterType[types.length];
        for (int i = 0; i < parameterTypes.length; i++) {
            Class<?> componentType = null;
            if (Collection.class.isAssignableFrom(types[i])) {
                Object value = values[i];
                if (value != null && ((Collection<?>)value).size() > 0) {
                    componentType = ((Collection<?>) value).iterator().next().getClass();
                }
            }
            parameterTypes[i] = new ParameterType(types[i], componentType);
        }
        RpcRequest request = new RpcRequest(beanName, methodName, parameterTypes, values);
        RpcClientResponse response = clients.get().send(request);
        clients.recodeResponseTime(response);


        response.throwException();
        return response.getResult();
    }
}
